import { ref, reactive, onUnmounted, onMounted, nextTick } from "vue";
import {
  Leafer,
  App,
  Text,
  Image,
  ImageEvent,
  ZoomEvent,
  ResizeEvent,
  ChildEvent,
  LeaferEvent,
  PropertyEvent,
  Group,
  ImageManager,
  Frame,
  Line,
  Box,
  MoveEvent
} from "leafer-ui";

import "@leafer-in/editor";
import "@leafer-in/view";
import "@leafer-in/animate";
import "@leafer-in/viewport";
import "@leafer-in/state";
import "@leafer-in/export";
import "@leafer-in/find";
import '@leafer-in/motion-path' // 导入运动路径插件 //
import { Flow } from "@leafer-in/flow";
import { isFunction } from "@/utils/is";
import { useDebounceFn, useEventListener } from "@vueuse/core";
import useHistoryUtil from "./useHistoryUtil";
import { Message } from "@arco-design/web-vue";

const zoomConfig = {
  step: 0.1,
  min: 0.1,
  max: 5,
  padding: 0,
};
export const useDrawing = (containerId: string) => {
  // 初始化Leafer
  let app: App;
  let box: Group;
  let flow: Flow;
  const activeTool = ref("");
  const loading = ref(false);
  let fitScale = 1;
  const scale = ref(1);
  const dragable = ref(false);
  let boxList: Group[] = [];
  const target = (index: number = 0) => boxList[index];
  const historyUtil = useHistoryUtil((v: any) => {
    target().set({
      children: v ?? [],
    });
  });
  const commitHistory = () => {
    historyUtil.commit(target().toJSON().children ?? []);
  };

  //重写 setCursor 方法
  const initCursorManager = () => {
    if (!app.interaction) return;
    const originalSetCursor = app.interaction.setCursor;
    app.interaction.setCursor = function (cursor) {
      // 调用原始方法
      originalSetCursor.call(this, cursor);
      // 同步设置到父页面
      try {
      } catch (e) {
        // 处理跨域错误
      }
    };
  };
  const init = () => {
    app = new App({
      view: containerId,
      editor: {
        //是否启用框选功能
        boxSelect: false,
        editBox: !false,
      },
      smooth: true,
      // pointer: { touch: true },
      // touch: { preventDefault: true },
      move: {
        holdRightKey: true,
      },
      wheel: {
        moveSpeed: 0,
      },
    });
    app.on(ZoomEvent.ZOOM, function () {
      scale.value = +(app.tree.scale ?? 1) / fitScale;
    });
    //监听画布大小改变
    app.on(ResizeEvent.RESIZE, () => {
      hanResize();
    });
    app.on(LeaferEvent.READY, () => {
      initCursorManager();
    });
    flow = new Flow({
      flowAlign: "center", // 居中对齐 //
      children: [],
      width: 3000,
      // height: 1200,
      flowWrap: true, // 沿 X 轴自动换行 //
      // gap: { x: 8, y:8  },
    });
    app.tree.add(flow);
  };
  const initData = (dataStr: string | undefined | null) => {
    // if (target()) {
    //   app.tree.remove(target());
    // }
    // box = new Frame({
    //   x: 0,
    //   y: 0,
    //   width: bgImageList?.width ?? 0,
    //   height: bgImageList?.height ?? 0,
    //   zIndex: 1,
    //   fill: "transparent",
    //   overflow: "hide",
    // });
    // app.tree.add(target());
    // if (!!dataStr) {
    //   const data = JSON.parse(dataStr);
    //   historyUtil.init(data);
    // } else {
    //   console.log("target()", target().toJSON().children);
    //   historyUtil.init(target().toJSON().children);
    // }
  };
  const initRotate = () => {
    if (!app?.tree) return;
    if (app.tree.rotation === 0) return;
    app.tree.rotateOf("center", -(app.tree.rotation || 0));
  };
  const initFitScale = () => {
    app.tree.zoom("fit", zoomConfig.padding);
    scale.value = 1;
    fitScale = +(app.tree.scale ?? 1);
    app.data.fitScale = fitScale;
    app.config.zoom = {
      min: zoomConfig.min * fitScale,
      max: zoomConfig.max * fitScale,
    };
  };
  const initImg = async (data: { url: string[]; penData: string[] }) => {
    try {
      loading.value = true;
      if (boxList) {
        app.tree?.remove?.(boxList);
        initRotate();
      }
      // if (!data?.url) {
      //   reject();
      // }
      const loadImgList = data.url.map((item) => {
        const img = new Image({
          url: item,
          pixelRatio: 1,
          hittable: false,
          // zIndex: 0,
        });
        img.load();
        return new Promise<Image>((resolve, reject) => {
          img.once(ImageEvent.LOADED, async (e: ImageEvent) => {
            console.log("img",e)
            resolve(img);
          });
          img.once(ImageEvent.ERROR, () => {
            reject();
          });
        });
      });
      const imgList = await Promise.all(loadImgList);
      boxList = imgList.map((item) => {
        console.log("width",item?.width)
        return new Frame({
          width: item?.width ?? 0,
          height: item?.height ?? 0,
          fill: "transparent",
          overflow: "hide",
          children: [item],
        });
      });
      flow.add(boxList);
      initFitScale();
      // initData(data.penData);
    } catch (error) {
      Message.error("图片加载失败");
    } finally {
      loading.value = false;
    }
  };
  const hanResize = useDebounceFn(() => {
    if (!app.ready) return;
    if (!flow) return;
    // app.tree.zoom(flow, zoomConfig.padding, !true, 0.2);
    scale.value = 1;
  }, 300);

  const hanRotate = (isLeft: boolean) => {
    app.tree.rotateOf("center", isLeft ? -90 : 90);
  };
  const hanScale = (isAdd: boolean) => {
    const step = zoomConfig.step;
    let newScale = scale.value + (isAdd ? step : -step);
    if (newScale < zoomConfig.min) newScale = zoomConfig.min;
    if (newScale > zoomConfig.max) newScale = zoomConfig.max;
    scale.value = newScale;
    const target = newScale * fitScale;
    app.zoom(target, zoomConfig.padding, false, 0.2);
  };
  const clear = () => {
    target().clear();
    historyUtil.commit(target().toJSON().children);
  };
  onMounted(() => {
    init();
  });
  // 清理资源
  onUnmounted(() => {
    app.destroy();
  });
  useEventListener("unload", () => {
    const { list } = Leafer;
    list.forEach((leafer) => (leafer as Leafer).destroy(true));
    list.destroy();
    ImageManager.destroy();
  });
  const destroy = () => {
    app.destroy();
  };
  const setDragable = (v: boolean) => {
    dragable.value = v;
    app.config.move = {
      ...(app.config.move || {}),
      drag: v,
    };
  };
  return {
    activeTool,
    initImg,
    historyUtil,
    hanRotate,
    hanScale,
    clear,
    loading,
    scale,
    destroy,
    setDragable,
    dragable,
    target,
    getApp: () => app,
  };
};
